const axios = require('axios')
const configModel = require('@/models/config.model')
const trash = require('@/utils/ini.unit')
const { getAsync, setexAsync } = require('@/redis')
const { analyzeIp, analyzeIspFromIp } = require('@/utils/common.util')
const FormData = require('form-data')
const fs = require('fs')

function apiCreateQRCode ({ accessToken, path }) {
  return new Promise((resolve, reject) => {
    axios({
      method: 'post',
      url: `https://api.weixin.qq.com/wxa/getwxacode?access_token=${accessToken}`,
      data: {
        path,
        width: 280,
        is_hyaline: true
      },
      responseType: 'arraybuffer'
    }).then(response => {
      if (Object.prototype.toString.call(response.data) === '[object Uint8Array]') {
        resolve(Buffer.from(response.data, 'binary').toString('base64'))
      } else {
        reject(response.data)
      }
    }).catch(error => {
      reject(error)
    })
  })
}

function apiLoginMiniWeb (code) {
  return new Promise((resolve, reject) => {
    axios({
      method: 'post',
      url: 'https://api.weixin.qq.com/sns/jscode2session',
      params: {
        appid: trash.appid,
        secret: trash.secret,
        js_code: code,
        grant_type: 'authorization_code'
      }
    }).then(response => {
      if (response.status === 200 && !response.data?.errcode) {
        resolve(response.data)
      } else {
        reject(response.data)
      }
    }).catch(error => {
      reject(error)
    })
  })
}

/**
 * 根据ip地址解析出ip地址的经纬度和具体位置
 * @param {*} ip
 * @returns
 */
async function apiGetIPAddress (ip) {
  try {
    let ipdata = await getAsync(`ip--${ip}`)
    if (ipdata) {
      return JSON.parse(ipdata)
    }
    let baiduAK = await getAsync('baiduAK')
    if (!baiduAK) {
      const config = await configModel.find()
      baiduAK = config.baiduAK
      setexAsync('baiduAK', 60 * 60, baiduAK)
    }
    const response = await axios({
      method: 'get',
      url: `https://api.map.baidu.com/location/ip?ip=${ip}&coor=bd09ll&ak=${baiduAK}`
    })
    const jsonpData = response.data
    if (jsonpData.status === 0) {
      const content = jsonpData.content
      const addressDetail = content.address_detail
      const point = content.point
      const isp = analyzeIspFromIp(ip)
      const lonlat = await transformGeoconv(`${point.x},${point.y}`, baiduAK)
      ipdata = addressDetail.city
        ? {
            ip,
            isp,
            address: content.address,
            province: addressDetail.province,
            city: addressDetail.city || addressDetail.province,
            lonlat
          }
        : analyzeIp(ip)
    } else {
      ipdata = analyzeIp(ip)
    }
    setexAsync(`ip--${ip}`, 60 * 60, JSON.stringify(ipdata))
    return ipdata
  } catch (error) {
    throw new Error(error)
  }
}

/**
 * 百度坐标系转高德坐标系
 * @param {*} coords
 * @param {*} ak
 * @returns
 */
async function transformGeoconv (coords, ak) {
  const response = await axios({
    method: 'get',
    url: `https://api.map.baidu.com/geoconv/v1/?coords=${coords}&from=5&to=3&ak=${ak}`
  })
  const jsonpData = response.data
  if (jsonpData.status === 0) {
    const data = jsonpData.result[0]
    return `${data.y},${data.x}`
  }

  return coords
}

function apiFuzzySearchByName (name) {
  return new Promise((resolve, reject) => {
    axios({
      method: 'get',
      url: `http://127.0.0.1:5656/api/v1/tool?name=${name}`
    }).then(response => {
      if (response.status === 200 && response.data?.code === '0') {
        return resolve(response.data.data)
      }
      resolve([])
    }).catch(error => {
      reject(error)
    })
  })
}

function apiGetToolTree (userId) {
  return new Promise((resolve, reject) => {
    axios({
      method: 'get',
      url: `http://127.0.0.1:5656/api/v1/tool/tree-list?userId=${userId}`
    }).then(response => {
      if (response.status === 200 && response.data?.code === '0') {
        return resolve(response.data.data)
      }
      resolve([])
    }).catch(error => {
      reject(error)
    })
  })
}

function apiUploadImages (filePath, waterText = '0') {
  const data = new FormData()
  data.append('file', fs.createReadStream(filePath))
  data.append('waterText', waterText)
  return new Promise((resolve, reject) => {
    axios({
      method: 'post',
      url: 'https://image.zdxblog.cn/upload/uploadFile',
      data,
      headers: { 'Content-Type': `multipart/form-data; boundary=${data.getBoundary}` }
    }).then(response => {
      resolve(response.data)
    }).catch(error => {
      reject(error)
    })
  })
}

/**
 * 根据gitee code获取gitee token
 * @param {*} code
 * @returns
 */
function apiGetGiteeAccesstokenByCode (code) {
  const params = {
    grant_type: 'authorization_code',
    code,
    client_id: '57a64666d7aa79411b3352e8805b6e52cf0c64d415e56756c7414a914e01dac8',
    client_secret: '5d2715b359130350ec766ed899bf791826128d40cfece4fc8dfb7a8d57797ee0',
    redirect_uri: 'https://gimi.zdxblog.cn/'
  }
  return new Promise((resolve, reject) => {
    axios({
      method: 'post',
      url: 'https://gitee.com/oauth/token',
      params
    }).then(response => {
      if (response.status === 200 && response.data?.access_token) {
        return resolve(response.data.access_token)
      }
      reject(response.data)
    }).catch(error => {
      reject(error.response.data)
    })
  })
}

/**
 * 根据accesstoken获取gitee用户信息
 * @param {*} accessToken
 * @returns
 */
async function apiGetGiteeUserInfo (accessToken) {
  const params = {
    access_token: accessToken
  }
  return new Promise((resolve, reject) => {
    axios({
      method: 'get',
      url: 'https://gitee.com/api/v5/user',
      params
    }).then(response => {
      if (response.status === 200 && response.data?.id) {
        return resolve(response.data)
      }
      reject(response.data)
    }).catch(error => {
      reject(error.response.data)
    })
  })
}

/**
 * 根据github code获取github token
 * @param {*} code
 * @returns
 */
function apiGetGithubAccesstokenByCode (code) {
  const params = {
    code,
    client_id: 'Ov23liCiZWWku8B1MMog',
    client_secret: '5d7363706b62fb83ea905725e2275374f931cc83'
  }
  return new Promise((resolve, reject) => {
    axios({
      method: 'post',
      url: 'https://github.com/login/oauth/access_token',
      params
    }).then(response => {
      if (response.status === 200) {
        return resolve(response.data.split('&')[0].split('=')[1])
      }
      reject(response.data)
    }).catch(error => {
      reject(error.response.data)
    })
  })
}

/**
 * 根据accesstoken获取gitee用户信息
 * @param {*} accessToken
 * @returns
 */
async function apiGetGithubUserInfo (accessToken) {
  return new Promise((resolve, reject) => {
    axios({
      method: 'get',
      url: 'https://api.github.com/user',
      headers: {
        Authorization: `token ${accessToken}`
      }
    }).then(response => {
      if (response.status === 200 && response.data?.id) {
        return resolve(response.data)
      }
      reject(response.data)
    }).catch(error => {
      reject(error.response.data)
    })
  })
}

module.exports = {
  apiCreateQRCode,
  apiLoginMiniWeb,
  apiGetIPAddress,
  apiGetToolTree,
  apiFuzzySearchByName,
  apiUploadImages,
  apiGetGiteeAccesstokenByCode,
  apiGetGiteeUserInfo,
  apiGetGithubAccesstokenByCode,
  apiGetGithubUserInfo
}
